package com.yida.gwj.basis.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.text.Convert;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.service.RemoteGwjConfigService;
import com.yida.gwj.basis.domain.*;
import com.yida.gwj.basis.domain.dto.GwjInitApiHouseDTO;
import com.yida.gwj.basis.domain.dto.GwjInitApiOwnerDTO;
import com.yida.gwj.basis.domain.request.GwjInitApiRequest;
import com.yida.gwj.basis.domain.request.GwjInitBusinessSaveSubmitRequest;
import com.yida.gwj.basis.enums.GwjInitBusinessBuildStatus;
import com.yida.gwj.basis.service.*;
import com.yida.gwj.common.constant.GwjConstants;
import com.yida.gwj.common.domain.*;
import com.yida.gwj.common.enums.GwjBusinessFlagType;
import com.yida.gwj.common.enums.GwjBusinessHouseStatus;
import com.yida.gwj.common.enums.GwjBusinessStatus;
import com.yida.gwj.common.enums.StepConfigInfoEnum;
import com.yida.gwj.common.service.*;
import com.yida.gwj.common.utils.GwjConvertUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 小区基础数据初始化（基础数据管理模块）Service业务层处理
 *
 * @author lqq
 * @date 2022-11-15
 */
@Service
public class GwjInitDataInitBusinessServiceImpl implements IGwjInitDataInitBusinessService {

	@Resource
	private IGwjInitBusinessLogService logService;

	@Resource
	private IGwjBaseBusinessNumService businessNumService;

	@Resource
	private IGwjInitBusinessService businessService;

	@Resource
	private IGwjInitBusinessCommunityService businessCommunityService;

	@Resource
	private IGwjInitBusinessBuildService businessBuildService;

	@Resource
	private IGwjInitBusinessHouseService businessHouseService;

	@Resource
	private IGwjInitBusinessOwnerService businessOwnerService;

	@Resource
	private IGwjInitApiService apiService;

	@Resource
	private IGwjBaseCommunityService communityService;

	@Resource
	private IGwjBaseBuildService buildService;

	@Resource
	private IGwjBaseHouseService houseService;

	@Resource
	private IGwjBaseOwnerService ownerService;

	@Resource
	private RemoteGwjConfigService remoteGwjConfigService;

	/**
	 * 小区基础数据初始化（保存）
	 *
	 * @param saveSubmitRequest 请求参数
	 * @return /
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long saveBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
		GwjInitBusiness business = saveSubmitRequest.getBusiness();
		GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
		List<GwjInitBusinessBuild> builds = saveSubmitRequest.getBusinessBuilds();
		//处理业务信息
		//业务流程
		business.setFlowId(remoteGwjConfigService.selectGwjConfBusinessFlagByBizFlagId(business.getBizFlagId(), SecurityConstants.INNER).getData().getFlowId());
		//地区
		business.setAreaId(community.getAreaId());
		//TODO 获取业务编号加锁
		GwjBaseBusinessNum businessNum = businessNumService.getNextNum(business.getAreaId(), business.getBizFlagId());
		//业务编号
		business.setBizNum(Convert.toLong(businessNum.toString()));
		//业务名称
		if (StringUtils.isBlank(business.getBizName())) {
			business.setBizName(community.getCommunityName());
		}
		businessService.insert(business);
		//处理业务小区信息
		community.setBizId(business.getBizId());
		//保存小区信息
		businessCommunityService.save(community);
		//保存其他业务数据
		saveDataByStatus(builds, community);
		//日志
		logService.addSaveLog(business);
		return business.getBizId();
	}

	/**
	 * 通过楼栋的状态保存
	 *
	 * @param builds    /
	 * @param community /
	 */
	public void saveDataByStatus(List<GwjInitBusinessBuild> builds, GwjInitBusinessCommunity community) {
		//删除
		List<GwjInitBusinessBuild> del = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.DEL.getCode())).collect(Collectors.toList());
		if (StringUtils.isNotEmpty(del)) {
			businessBuildService.deleteByList(del, community.getBizId());
		}
		//保存修改
		List<GwjInitBusinessBuild> update = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.UPDATE.getCode())).collect(Collectors.toList());
		if (StringUtils.isNotEmpty(update)) {
			update.forEach(b -> {
				b.setAreaId(community.getAreaId());
				b.setStreetId(community.getStreetId());
				b.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
				b.setUpdateTime(DateUtils.getNowDate());
			});
			businessBuildService.updateBatch(update);
			//查询楼栋下房屋信息
			String[] buildCodes = update.stream().map(GwjBaseBusinessBuild::getBuildCode).toArray(String[]::new);
			List<GwjInitBusinessHouse> houses = businessHouseService.getList(buildCodes, community.getBizId());
			if (StringUtils.isNotEmpty(houses)) {
				houses.forEach(h -> {
					h.setAreaId(community.getAreaId());
					h.setStreetId(community.getStreetId());
					h.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
					h.setUpdateTime(DateUtils.getNowDate());
				});
				businessHouseService.updateBatch(houses);
				String[] houseCodes = houses.stream().map(GwjBaseBusinessHouse::getHouseCode).toArray(String[]::new);
				List<GwjInitBusinessOwner> owners = businessOwnerService.getList(houseCodes, community.getBizId());
				if (StringUtils.isNotEmpty(owners)) {
					owners.forEach(o -> {
						o.setAreaId(community.getAreaId());
						o.setStreetId(community.getStreetId());
						o.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
						o.setUpdateTime(DateUtils.getNowDate());
					});
					businessOwnerService.updateBatch(owners);
				}
			}
		}
		//新增
		List<GwjInitBusinessBuild> add = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.ADD.getCode())).collect(Collectors.toList());
		if (StringUtils.isEmpty(update) && StringUtils.isEmpty(add)) {
			throw new ServiceException("请选择楼栋");
		}
		if (StringUtils.isNotEmpty(add)) {
			//新增
			for (GwjInitBusinessBuild build : add) {
				build.setBizId(community.getBizId());
				build.setAreaId(community.getAreaId());
				build.setStreetId(community.getStreetId());
				build.setBizCommunityId(community.getBizCommunityId());
				build.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
				build.setCreateTime(DateUtils.getNowDate());
				//保存业务房屋信息
				GwjInitApiRequest apiRequest = new GwjInitApiRequest();
				apiRequest.setAreaId(community.getAreaId());
				apiRequest.setBuildCode(build.getBuildCode());
				List<GwjInitApiHouseDTO> apiHouseData = apiService.getHouse(apiRequest);
				//房屋不为空
				if (StringUtils.isNotEmpty(apiHouseData)) {
					List<GwjInitBusinessHouse> businessHouses = GwjConvertUtil.convertList(apiHouseData, GwjInitBusinessHouse.class);
					for (GwjInitBusinessHouse businessHouse : businessHouses) {
						businessHouse.setBizId(community.getBizId());
						businessHouse.setAreaId(community.getAreaId());
						businessHouse.setStreetId(community.getStreetId());
						businessHouse.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
						businessHouse.setCreateTime(DateUtils.getNowDate());
					}
					businessHouses = businessHouses.stream().map(item -> {
						if(ObjectUtil.isEmpty(item.getForecastSize())){
							item.setForecastSize(BigDecimal.ZERO);
						}
						if(ObjectUtil.isEmpty(item.getActualSize())){
							item.setActualSize(BigDecimal.ZERO);
						}
						return item;
					}).collect(Collectors.toList());
					//保存房屋数据
					businessHouseService.saveBatch(businessHouses);
					//分段拉取业主信息
					List<String> houseCodes = businessHouses.stream().map(GwjBaseBusinessHouse::getHouseCode).collect(Collectors.toList());
					List<List<String>> codeList = GwjConvertUtil.partition(houseCodes, 10);
					for (List<String> list : codeList) {
						String houseCodeStr = StringUtils.join(list, ",");
						//保存业务业主信息
						GwjInitApiRequest apiRequest2 = new GwjInitApiRequest();
						apiRequest2.setAreaId(community.getAreaId());
						apiRequest2.setHouseCode(houseCodeStr);
						List<GwjInitApiOwnerDTO> apiOwnerData = apiService.getOwner(apiRequest2);
						//业主不为空
						if (StringUtils.isNotEmpty(apiOwnerData)) {
							List<GwjInitBusinessOwner> businessOwners = GwjConvertUtil.convertList(apiOwnerData, GwjInitBusinessOwner.class);
							businessOwners.forEach(owner -> {
								owner.setBizId(community.getBizId());
								owner.setAreaId(community.getAreaId());
								owner.setStreetId(community.getStreetId());
								owner.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
								owner.setCreateTime(DateUtils.getNowDate());
							});
							businessOwnerService.saveBatch(businessOwners);
						}
					}
				}
			}
			//保存业务楼栋信息
			businessBuildService.saveBatch(add);
		}
	}

	/**
	 * 小区基础数据初始化（保存修改）
	 *
	 * @param saveSubmitRequest 请求参数
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
		GwjInitBusiness business = saveSubmitRequest.getBusiness();
		GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
		List<GwjInitBusinessBuild> businessBuilds = saveSubmitRequest.getBusinessBuilds();
		//检验当前登录账号是否有权限
		businessService.checkPermission(business.getBizId());
		business.setStatus(GwjBusinessStatus.NORMAL.getCode());
		business.setAreaId(community.getAreaId());
		businessService.updateById(business);
		//保存业务小区信息
		community.setBizId(business.getBizId());
		if (StringUtils.isNull(community.getBizCommunityId())) {
			businessCommunityService.save(community);
		} else {
			businessCommunityService.updateById(community);
		}
		saveDataByStatus(businessBuilds, community);
		//日志
		logService.addSaveLog(business);
	}

    /**
     * 小区基础数据初始化（提交）
     *
     * @param saveSubmitRequest 请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
        GwjInitBusiness business = saveSubmitRequest.getBusiness();
        GwjInitBusinessLog businessLog = saveSubmitRequest.getBusinessLog();
        GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
        List<GwjInitBusinessBuild> builds = saveSubmitRequest.getBusinessBuilds();
        if (StringUtils.isNull(business.getBizId())) {
            throw new ServiceException("请先保存业务");
        }
        //判断是否已有数据 可以直接提交
        if (StringUtils.isNull(businessCommunityService.getOne(business.getBizId())) && StringUtils.isNull(community)) {
            throw new ServiceException("小区信息不能为空");
        }
        if (StringUtils.isEmpty(businessBuildService.getListByBizId(business.getBizId())) && StringUtils.isEmpty(builds)) {
            throw new ServiceException("小区楼栋不能为空");
        }
        //检验当前登录账号是否有权限
        businessService.checkPermission(business.getBizId());
        //设置日志流程步骤,业务编号
        businessLog.setStepId(business.getStepId());
        businessLog.setBizId(business.getBizId());
        //获取当前步骤所有配置
        List<String> configInfos = remoteGwjConfigService.selectGwjConfStepConfigInfoCodeListByBizFlagId(businessLog.getStepId(), SecurityConstants.INNER).getData();
        //判断是否需要选收件人
        if (StringUtils.containsAny(configInfos, StepConfigInfoEnum.SUBMIT_CHOOSE_USER.getCode()) && StringUtils.isAnyBlank(Convert.toStr(businessLog.getUserId()), businessLog.getRealName())) {
            throw new ServiceException("请选择下一位收件人");
        }
        //当前办理人员
        business.setCurrentOperId(StringUtils.isNull(businessLog.getUserId()) ? SecurityUtils.getUserId() : businessLog.getUserId());
        business.setCurrentOperName(StringUtils.isBlank(businessLog.getRealName()) ? SecurityUtils.getLoginUser().getSysUser().getRealName() : businessLog.getRealName());
        //设置下一步步骤
        GwjConfStep nextStep = remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.INIT.getCode(), business.getStepId(), SecurityConstants.INNER).getData();
        business.setStepId(nextStep.getStepId());
        //更新业务
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        businessService.updateById(business);
        //判断当前流程是否可以编辑
        if (StringUtils.containsAny(configInfos, StepConfigInfoEnum.SUBMIT_EDIT.getCode())) {
            if (StringUtils.isNotNull(community) && StringUtils.isNotEmpty(builds)) {
                //保存业务小区、楼栋、房屋、业主等信息
                community.setBizId(business.getBizId());
                if (StringUtils.isNull(community.getBizCommunityId())) {
                    businessCommunityService.save(community);
                } else {
                    businessCommunityService.updateById(community);
                }
                saveDataByStatus(builds, community);
            }
        }
        //日志
        logService.addSubmitLog(business, businessLog);
        //判断下一步步骤是不是已经最后一步
        if (StringUtils.isNull(remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.INIT.getCode(), nextStep.getStepId(), SecurityConstants.INNER).getData())) {
            //将业务数据插入基础数据
            //小区数据
            GwjInitBusinessCommunity businessCommunity = businessCommunityService.getOne(business.getBizId());
            GwjBaseCommunity baseCommunity = GwjConvertUtil.convert(businessCommunity, GwjBaseCommunity.class);
            communityService.insertGwjBaseCommunity(baseCommunity);
            //楼栋数据
            List<GwjInitBusinessBuild> businessBuilds = businessBuildService.getListByBizId(business.getBizId());
            List<GwjBaseBuild> baseBuilds = GwjConvertUtil.convertList(businessBuilds, GwjBaseBuild.class);
            baseBuilds.forEach(build -> {
                build.setCommunityId(baseCommunity.getCommunityId());
                build.setTotalLayer(ObjectUtil.isNull(build.getTotalLayer()) ? 0 : build.getTotalLayer());
                build.setPublicFlag(GwjConstants.NO);
                build.setUpdateBy("");
                build.setUpdateTime(null);
            });
            buildService.insertBatchGwjBaseBuild(baseBuilds);
            //房屋数据
            List<GwjInitBusinessHouse> businessHouses = businessHouseService.getList(GwjBusinessHouseStatus.CONFIRM.getCode(), business.getBizId());
            if (StringUtils.isNotEmpty(businessHouses)) {
                List<GwjBaseHouse> baseHouses = GwjConvertUtil.convertList(businessHouses, GwjBaseHouse.class);
                baseHouses.forEach(bh -> {
                    bh.setPublicFlag(GwjConstants.NO);
                    bh.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
                    bh.setCreateTime(DateUtils.getNowDate());
                    bh.setDepositMoney(BigDecimal.ZERO);
                    bh.setDepositSize(BigDecimal.ZERO);
                    bh.setAddedMoney(BigDecimal.ZERO);
                    bh.setUsedMoney(BigDecimal.ZERO);
                    bh.setBlockedMoney(BigDecimal.ZERO);
                    bh.setInterestMoney(BigDecimal.ZERO);
                    bh.setCurrentMoney(BigDecimal.ZERO);
                    bh.setUpdateBy("");
                    bh.setUpdateTime(null);
                });
                houseService.insertBatchGwjBaseHouse(baseHouses);
                //业主数据
                String[] houseCodes = businessHouses.stream().map(GwjBaseBusinessHouse::getHouseCode).toArray(String[]::new);
                List<GwjInitBusinessOwner> businessOwners = businessOwnerService.getList(houseCodes, business.getBizId());
                if (StringUtils.isNotEmpty(businessOwners)) {
                    ownerService.insertBatchGwjBaseOwner(GwjConvertUtil.convertList(businessOwners, GwjBaseOwner.class));
                }
            }
            //业务更新为完结
            business.setStatus(GwjBusinessStatus.FINISH.getCode());
            businessService.updateById(business);
            logService.addFinishLog(business);
        }
    }

    /**
     * 小区分户清册小区详情
     *
     * @param bizId 业务ID
     * @return /
     */
    @Override
    public GwjInitBusinessCommunity getCommunityDetail(Long bizId) {
        GwjInitBusinessCommunity community = businessCommunityService.getOne(bizId);
        if (StringUtils.isNotNull(community)) {
            //查询所有已选择中房屋
            List<GwjInitBusinessHouse> houses = businessHouseService.getList(GwjBusinessHouseStatus.CONFIRM.getCode(), bizId);
            if (StringUtils.isNotEmpty(houses)) {
                community.setTotalOwner(houses.size());
                BigDecimal bigDecimal = new BigDecimal("0.00");
                for (GwjInitBusinessHouse h : houses) {
                    if (h.getActualSize().intValue() != 0) {
                        bigDecimal = bigDecimal.add(h.getActualSize());
                    } else {
                        bigDecimal = bigDecimal.add(h.getForecastSize());
                    }
                }
                community.setTotalSize(bigDecimal);
            }
        }
        return community;
    }
}
